package com.hmdp.entity.result;

import com.hmdp.constant.HttpStatus;
import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 通用返回结果，服务端响应的数据最终都会封装成此对象
 * @param <T>
 */
@Data
public class R<T> implements Serializable {
    /**
     * 状态码
     */
    protected Integer code;

    /**
     * 响应信息
     */
    protected String message;

    /**
     * 返回数据
     */
    private T data;

    /**
     * 动态数据
     */
    private Map map;

    public R() {
        map = new HashMap();
    }

    public R(T data, Integer code) {
        this.data = data;
        this.code = code;
    }

    public R(Integer code, String msg) {
        this.code = code;
        this.message = msg;
    }

    public R(T data, Integer code, String msg) {
        this.data = data;
        this.code = code;
        this.message = msg;
    }

    /**
     * 成功，无数据返回，状态码为200
     */
    public static <T> R<T> success() {
        return new R<>(null, HttpStatus.SUCCESS);
    }

    /**
     * 成功，有数据返回，状态码为200
     *
     * 返回String类型的data时，请使用：
     * R<String> r = new R<>();
     * r.setData(dataStr);
     * r.setCode(200);
     * r.setMessage("xxx")
     * return r;
     */
    public static <T> R<T> success(T data) {
        return new R<>(data, HttpStatus.SUCCESS);
    }

    /**
     * 成功，无数据返回，状态码为200，指定提示信息（若成功时无需返回提示信息，则可以删除该方法）
     */
    public static <T> R<T> success(String msg) {
        return new R<>(HttpStatus.SUCCESS, msg);
    }

    /**
     * 成功，有数据返回，状态码为200，指定提示信息
     */
    public static <T> R<T> success(T data, String msg) {
        return new R<>(data, HttpStatus.SUCCESS, msg);
    }

    /**
     * 失败，无数据返回，状态码为500，指定提示信息
     */
    public static <T> R<T> fail(String msg) {
        return new R<>(HttpStatus.ERROR, msg);
    }

    /**
     * 失败，无数据返回，指定状态码，指定提示信息
     */
    public static <T> R<T> fail(Integer code, String msg) {
        return new R<>(code, msg);
    }

    /**
     * 动态数据Map使用示例：
     * R<Object> r = new R<>();
     * r.setData(data);
     * r.setCode(200);
     * r.setMessage("xxx")
     * r.add(k1, v1).add(k2, v2).add(k3, v3);
     * return r;
     */
    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }
}
